﻿using MvcSmartTool.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MvcSmartTool.DomainGenerator {
    public class DomainProjectWriter : BaseProjectWriter {
        private static Guid s_projectGuid;
        #region Constructors
        public override string ProjectName {
            get {
                return SolutionName + ".Domain";
            }
        }
        public DomainProjectWriter(string solutionName) :base(solutionName){
            Models = new List<TypeGenerationModel>();
            SolutionName = solutionName;
        }
        public DomainProjectWriter(string solutionName, string output)
            : base(solutionName) {
            OutputPath = output;
        }
        public DomainProjectWriter(string solutionName, IList<TypeGenerationModel> models)
            : this(solutionName) {
            Models = models;
            OutputPath = Path.Combine("./", ProjectName);
        }
        #endregion End Constructors
        #region Methods
        protected override void InternalGenerate() {
            //Copy all common files (Constants, Extension ...)
            CopyTemplate("Constants", ProjectPath, SolutionName);
            CopyTemplate("LamdaExtension", ProjectPath, SolutionName);
            CopyTemplate("BaseRepository", ProjectPath, SolutionName);
            CopyTemplate("Enums", ProjectPath, SolutionName);
            //
            GenerateModel();
            GenerateRepositoryInterface();
            GenerateServiceInterface();
            GenerateCriteria();
            GenerateGridColumns();
            GenerateProjectFile();
        }
        private void GenerateProjectFile() {
            var template = new DomainProjectTemplate() {
                Model = Models,
                SolutionName = SolutionName
            };
            FileWriterHelper.WriteFile(ProjectPath, ProjectName +".csproj", template.TransformText());
            // Generate Assembly Info file
            var ass = new CommonAssemblyInfo() {
                SolutionName = SolutionName
            };
            FileWriterHelper.WriteFile(Path.Combine(ProjectPath, "Properties"), "AssemblyInfo.cs", ass.TransformText());
        }
        private void GenerateModel() {
            var directory = Path.Combine(ProjectPath, "Models");
            //Copy user model template
            CopyTemplate("User", directory, SolutionName);

            // Generate all models
            
            CopyTemplate("BaseEntity", directory, SolutionName);
            foreach (var model in Models) {
                var modelTemplate = new DomainModelWriter() {
                    Model = model
                };
                FileWriterHelper.WriteFile(directory, model.Name + ".cs", modelTemplate.TransformText());
            }
        }
        private void GenerateRepositoryInterface() {
            var directory = Path.Combine(ProjectPath, "Interfaces");
            CopyTemplate("IRepository", directory, SolutionName);
            CopyTemplate("IUserRepository", directory, SolutionName);
            foreach (var model in Models) {
                var modelTemplate = new RepositoryInterfaceWriter() {
                    Model = model
                };
                FileWriterHelper.WriteFile(directory, "I" + model.Name + "Repository.cs", modelTemplate.TransformText());
            }
            var unitOfWork = new IUnitOfWork() {
                Namespace = SolutionName,
                Model = Models
            };
            FileWriterHelper.WriteFile(directory, "IUnitOfWork.cs", unitOfWork.TransformText());
        }
        private void GenerateServiceInterface() {
            var directory = Path.Combine(ProjectPath, "Interfaces");
            //Copy all service template
            CopyTemplate("IService", directory, SolutionName);
            CopyTemplate("IUserService", directory, SolutionName);
            //
            foreach (var model in Models) {
                var modelTemplate = new ServiceInterfaceWriter() {
                    Model = model
                };
                FileWriterHelper.WriteFile(directory, "I" + model.Name + "Service.cs", modelTemplate.TransformText());
            }
        }
        private void GenerateCriteria() {
            var directory = Path.Combine(ProjectPath, "Criteria");
            CopyTemplate("BaseCriteria", directory, SolutionName);
            CopyTemplate("UserCriteria", directory, SolutionName);
            foreach (var model in Models) {
                var modelTemplate = new CriteriaWriter() {
                    Model = model
                };
                FileWriterHelper.WriteFile(directory, model.Name + "Criteria.cs", modelTemplate.TransformText());
            }
        }
        private void GenerateGridColumns() {
            var modelTemplate = new GridColumns() {
                Model = Models,
                Namespace = SolutionName
            };
            FileWriterHelper.WriteFile(ProjectPath, "GridCols.cs", modelTemplate.TransformText());
        }
        #endregion End Methods
        public static Guid ProjectGuid {
            get {
                if (s_projectGuid == Guid.Empty) {
                    s_projectGuid = Guid.NewGuid();
                }
                return s_projectGuid;
            }
        }
    }
}
